﻿using Leo.Awesome.Attachment.Enums;
using Leo.Awesome.Attachment.Services;
using Leo.Awesome.DictionaryManagement.Dtos;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Swashbuckle.AspNetCore.Annotations;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc;

namespace Leo.Awesome.Attachment.Controllers;

[Area(AttachmentServiceConsts.ModuleName)]
[RemoteService(Name = AttachmentServiceConsts.RemoteServiceName)]
[Route("api/[controller]")]
[SwaggerTag("附件管理")]
public class AttachmentController : AbpControllerBase
{
    private readonly IAttachmentService _attachmentService;
    public AttachmentController(IAttachmentService attachmentService)
    {
        _attachmentService = attachmentService;
    }


    [HttpPost("UploadFile")]
    [SwaggerOperation(
        Summary = "上传文件",
        Description = "",
        OperationId = "UploadFile",
        Tags = new[] { "Attachment" }
    )]
    public async Task<AttachmentGetOutPutDto> UploadFile(
       [SwaggerParameter("上传文件", Required = true)] IFormFile file,
       [SwaggerParameter("上传类型", Required = true)][FromForm] FolderType folderType,
       [SwaggerParameter("上传类型", Required = false)][FromForm] Guid? uploaderId,
       [SwaggerParameter("关联者", Required = false)][FromForm] string relatedTo

    )
    {
        var length = file.Length;
        if (length <= 0) throw new BusinessException("不能上传空文件");
        if (length > 10000000) throw new BusinessException("剩余空间不足!");
        if (file.FileName.Length > 100) throw new BusinessException($"【{file.Name}】文件名长度超过100个字符");
        using var fileStream = file.OpenReadStream();
        byte[] bytes = new Byte[length];
        fileStream.Read(bytes, 0, (int)length);
        var fileType = file.FileName.Substring(file.FileName.LastIndexOf('.') + 1);
        return await _attachmentService.CreateAsync(new AttachmentCreateUpdateInput
        {
            Filename = file.FileName,
            FileSize = bytes.Length,
            FolderType = folderType,
            StorageType = fileType,
            UploaderId = uploaderId,
            RelatedTo = relatedTo,
            FileContext = bytes
        });
    }


    [HttpPost("ReUploadFile")]
    [SwaggerOperation(
       Summary = "重新上传文件",
       Tags = new[] { "Attachment" }
   )]
    public async Task<AttachmentGetOutPutDto> ReUploadFile(
      [SwaggerParameter("上传文件", Required = true)] IFormFile file,
      [SwaggerParameter("附件Id", Required = true)] Guid id,
      [SwaggerParameter("上传类型", Required = true)][FromForm] FolderType folderType,
      [SwaggerParameter("上传类型", Required = false)][FromForm] Guid? uploaderId,
      [SwaggerParameter("关联者", Required = false)][FromForm] string relatedTo

   )
    {
        var length = file.Length;
        if (length <= 0) throw new BusinessException("不能上传空文件");
        if (length > 10000000) throw new BusinessException("剩余空间不足!");
        if (file.FileName.Length > 100) throw new BusinessException($"【{file.Name}】文件名长度超过100个字符");
        using var fileStream = file.OpenReadStream();
        byte[] bytes = new Byte[length];
        fileStream.Read(bytes, 0, (int)length);
        var fileType = file.FileName.Substring(file.FileName.LastIndexOf('.') + 1);
        return await _attachmentService.UpdateAsync(id,new AttachmentCreateUpdateInput
        {
            Id = id,
            Filename = file.FileName,
            FileSize = bytes.Length,
            FolderType = folderType,
            StorageType = fileType,
            UploaderId = uploaderId,
            RelatedTo = relatedTo,
            FileContext = bytes
        });
    }



    [HttpPost("UploadFiles")]
    [SwaggerOperation(
        Summary = "批量上传文件",
        Tags = new[] { "Attachment" }
    )]
    public async Task<List<AttachmentGetOutPutDto>> UploadFiles(
       [SwaggerParameter("上传文件", Required = true)] List<IFormFile> files,
       [SwaggerParameter("上传类型", Required = true)][FromForm] FolderType folderType,
       [SwaggerParameter("上传类型", Required = false)][FromForm] Guid? uploaderId,
       [SwaggerParameter("关联者", Required = false)][FromForm] string relatedTo

    )
    {
        // 参数验证
        if (files == null || files.Count == 0)
        {
            throw new BusinessException("不能上传空文件");
        }
        foreach (var file in files)
        {
            var length = file.Length;
            if (length <= 0) throw new BusinessException("不能上传空文件");
            if (length > 10000000) throw new BusinessException("剩余空间不足!");
            if (file.FileName.Length > 100) throw new BusinessException($"【{file.Name}】文件名长度超过100个字符");
        }
        var inputs = new List<AttachmentCreateUpdateInput>();
        foreach (var file in files)
        {
            using var memoryStream = new MemoryStream();
            await file.CopyToAsync(memoryStream).ConfigureAwait(false);
            inputs.Add(new AttachmentCreateUpdateInput
            {
                Id = Guid.NewGuid(),
                FileContext = file.GetAllBytes(),
                Filename = file.Name,
                FileSize = file.Length,
                FolderType = folderType,
                RelatedTo = relatedTo,
                UploaderId = uploaderId,
                Type = file.ContentType
            });

        }

        return await _attachmentService.InsertBatch(inputs);
    }

    [HttpPost("DownFile")]
    [SwaggerOperation(
    Summary = "下载文件",
    Tags = new[] { "Attachment" }
    )]
    public async Task<ActionResult> DownFile(Guid id)
    {
        try
        {

            var output = await _attachmentService.GetAsync(id);
            new FileExtensionContentTypeProvider().TryGetContentType(output.Filename, out string contentType);
            return File(fileContents: output.FileContext, contentType: contentType.IsNullOrEmpty() ? output.Type : contentType,
                fileDownloadName: output.Filename);
        }
        catch 
        {
            return NotFound();
        }
    }

    [HttpGet("GetById/{id}")]
    [SwaggerOperation(
        Summary = "获取明细",
        Tags = new[] { "Attachment" }
    )]
    public async Task<AttachmentGetOutPutDto> Get(Guid id)
    {
        return await _attachmentService.GetAsync(id);
    }

    [HttpPost("{id}/Delete")]
        [SwaggerOperation(
        Summary = "删除",
        Tags = new[] { "Attachment" }
    )]
    public async Task DeleteAsync(Guid id)
    {
        await _attachmentService.DeleteAsync(id);
    }

    [HttpPost("deletemany")]
    [SwaggerOperation(
     Summary = "批量删除",
     Tags = new[] { "Attachment" }
    )]
    public async Task DeleteManyAsync(List<Guid> ids)
    {
        await _attachmentService.DeleteManyAsync(ids);
    }

    [HttpPost("PageQuery")]
    [SwaggerOperation(
        Summary = "分页查询",
        Tags = new[] { "Attachment" }
    )]
    public async Task<PagedResultDto<AttachmentGetListOutputDto>> GetListAsync(AttachmentGetListPageInput input)
    {
        return await _attachmentService.GetListAsync(input);
    }

    [HttpPost("Query")]
    [SwaggerOperation(
    Summary = "查询",
    Tags = new[] { "Attachment" }
    )]
    public async Task<List<AttachmentGetListOutputDto>> Query([FromBody] AttachmentGetListInput getListInput)
    {
        return await _attachmentService.Query(getListInput);
    }

    [HttpPost("QueryCount")]
    [SwaggerOperation(
         Summary = "统计",
         Tags = new[] { "Attachment" }
    )]
    public async Task<long> QueryCount(AttachmentGetListInput getListInput)
    {
        return await _attachmentService.QueryCount(getListInput);
    }
}
